package com.manlitech.manlichat.base.netty.initializer;

import com.manlitech.manlichat.base.netty.handler.MyHttpRequestHandler;
import com.manlitech.manlichat.base.netty.handler.MyNettyExceptionHandler;
import com.manlitech.manlichat.base.netty.initializer.ssl.NettySsl;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class NettyServerHttpHandlerInitializer extends ChannelInitializer<Channel> {

    private Logger logger = LoggerFactory.getLogger(getClass());


    @Autowired
    MyHttpRequestHandler httpRequestHandler;

    @Autowired
    MyNettyExceptionHandler nettyExceptionHandler;

    @Autowired
    NettySsl nettySsl;

    /**
     * 心跳超时时间
     */
    // 读超时
    private static final int READ_IDEL_TIME_OUT = 10;
    // 写超时
    private static final int WRITE_IDEL_TIME_OUT = 15;
    // 所有超时
    private static final int ALL_IDEL_TIME_OUT = 20;



    @Override
    protected void initChannel(Channel ch) throws Exception {
        logger.info("收到新连接");

        // 获得 Channel 对应的 ChannelPipeline
        ChannelPipeline channelPipeline = ch.pipeline();
        // 添加一堆 NettyServerHandler 到 ChannelPipeline 中
        channelPipeline
                //证书
                .addLast("sslHandler", new SslHandler(nettySsl.getSslEngine()))
                // 空闲检测 http 不做长轮训则空闲检测无效
                //.addLast(new IdleStateHandler(READ_IDEL_TIME_OUT,WRITE_IDEL_TIME_OUT, ALL_IDEL_TIME_OUT, TimeUnit.SECONDS))
                //以块的方式来写的处理器，防止发送大文件时导致内存溢出， channel.write(new ChunkedFile(new File("bigFile.mkv")))
                .addLast(new ChunkedWriteHandler())
                // 将HttpMessage和HttpContents聚合到一个完成的 FullHttpRequest或FullHttpResponse中,具体是FullHttpRequest对象还是FullHttpResponse对象取决于是请求还是响应
                // 需要放到HttpServerCodec这个处理器后面
                .addLast(new HttpObjectAggregator(8192))
                //HTTP 编码解码
                .addLast(new HttpRequestDecoder())
                .addLast(new HttpResponseEncoder())
                /**
                 * netty http 请求处理
                 */
                // http 消息聚合器512*1024为接收的最大contentlength
                .addLast("httpAggregator",new HttpObjectAggregator(512*1024))
                // 请求处理器
                .addLast(httpRequestHandler)
                //全局异常捕获
                .addLast(nettyExceptionHandler);
    }

}